package com.douqu.game.main.service;


import com.alibaba.fastjson.JSONObject;
import com.bean.core.util.HttpJsonUtils;
import com.bean.core.util.MD5Utils;
import com.bean.core.util.TimeUtils;
import com.bean.core.util.Utils;
import com.douqu.game.core.config.FunctionConfig;
import com.douqu.game.core.config.MailConfig;
import com.douqu.game.core.config.RechargeConfig;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.database.model.*;
import com.douqu.game.core.e.E_MailModelType;
import com.douqu.game.core.e.E_PlayerStatus;
import com.douqu.game.core.e.E_RechargeGoodsType;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.common.TwoTuple;
import com.douqu.game.core.entity.db.MailDB;
import com.douqu.game.core.entity.ext.*;
import com.douqu.game.core.entity.ext.data.boon.BonusData;
import com.douqu.game.core.entity.ext.data.boon.OnlineRewardData;
import com.douqu.game.core.entity.ext.data.boon.RechargeRecordData;
import com.douqu.game.core.entity.ext.data.timeLimit.TimePropDB;
import com.douqu.game.core.entity.world.map.WorldMapData;
import com.douqu.game.core.factory.*;
import com.douqu.game.core.netty.NettyConnection;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGMainProto;
import com.douqu.game.core.protobuf.SGPlayerProto;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.PayUtils;
import com.douqu.game.core.util.SendUtils;
import com.douqu.game.core.web.request.RechargeParam;
import com.douqu.game.core.web.response.QueryRechargeCount;
import com.douqu.game.main.GameServer;
import com.douqu.game.main.database.mapper.read.ReadPlayerMapper;
import com.douqu.game.main.database.mapper.read.ReadUserMapper;
import com.douqu.game.main.database.mapper.write.*;
import com.douqu.game.main.server.SpringContext;
import com.douqu.game.main.util.MsgUtils;
import com.douqu.game.core.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

//import com.douqu.game.main.cache.RedisWrapperClient;

/**
 * Author : Bean
 * 2017-04-11 12:23
 */
@Service
public class PlayerServiceImpl implements PlayerService {


//    @Autowired
//    private RedisWrapperClient redisWrapperClient;

    @Autowired
    private ReadPlayerMapper readPlayerMapper;

    @Autowired
    private WritePlayerMapper writePlayerMapper;

    @Autowired
    private WriteLoginLogMapper writeLoginLogMapper;

    @Autowired
    private WriteLogoutLogMapper writeLogoutLogMapper;

    @Autowired
    private ReadUserMapper readUserMapper;

    @Autowired
    private WriteUserMapper writeUserMapper;

    @Autowired
    private WriteFeedbackMapper writeFeedbackMapper;

    @Autowired
    private WriteGMLogMapper writeGMLogMapper;

    @Autowired
    private JdbcTemplate jdbcTemplate;


    @Override
    public int update(Player player)
    {
        return writePlayerMapper.update(player.save());
    }

    @Override
    public int insert(PlayerModel playerModel) {
        return writePlayerMapper.insert(playerModel);
    }


    @Override
    public UserModel getUserByAccount(String account) {
        return readUserMapper.getByKey(account);
    }

    @Override
    public PlayerModel getPlayerByIndex(String objectIndex) {
        return readPlayerMapper.getPlayerByIndex(objectIndex);
    }

    @Override
    public List<PlayerModel> getPlayerListByIndex(List<String> indexList) {
        if(indexList.size() == 0)
            return new ArrayList<PlayerModel>();
        return readPlayerMapper.getPlayerListByIndex(indexList);
    }

    @Override
    public List<PlayerModel> getPlayerListByName(List<String> nameList) {
        if(nameList.isEmpty())
            return new ArrayList<PlayerModel>();
        return readPlayerMapper.getPlayerListByName(nameList);
    }


    @Override
    public List<PlayerModel> getPlayerByUid(Integer uid)
    {
        return readPlayerMapper.getPlayerByUid(uid);
    }

    @Override
    public List<PlayerModel> getAllPlayerList() {
        return readPlayerMapper.getAllPlayer();
    }

    @Override
    public PlayerModel getPlayerByName(String name) {
        return readPlayerMapper.getPlayerByName(name);
    }

    @Override
    public void loginLog(LoginLogModel loginLogModel)
    {
        writeLoginLogMapper.insert(loginLogModel);

        writePlayerMapper.login(new Date(), loginLogModel.getPlayerIndex());
    }

    @Override
    public void logoutLog(LogoutLogModel logoutLogModel)
    {
        writeLogoutLogMapper.insert(logoutLogModel);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Player regist(String account, String nickName, String password, String avatar,
                         SGCommonProto.E_CHANNEL_TYPE channel, SGCommonProto.E_CAMP_TYPE campType, String ip)
    {
        //创建角色
        UserModel user = new UserModel();
        user.setIp(ip);
        account = CoreUtils.createAccount(account, channel);
        if(channel == SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_QUICK){
            user.setDeviceId(account);
        }else {
            user.setAccount(account);
        }
        user.setChannel(channel.getNumber());
        if(!StringUtils.isNullOrEmpty(password)){
            user.setPassword(MD5Utils.encodeUppercase(password));
        }

        Date now = TimeUtils.getCurrentDate();

        user.setCreateTime(now);
        writeUserMapper.insert(user);

        Player player = new Player();
        player.name = nickName;
        if (StringUtils.isNullOrEmpty(avatar)){
            avatar = String.valueOf(campType.getNumber());
        }
        player.avatar = avatar;
        player.channel = channel.getNumber();
        player.camp = campType.getNumber();
        player.setUid(user.getId());
        player.setAccount(account);
        player.setObjectIndex(GameServer.getInstance().createPlayerIndex());
        //注册的时候只能在这里调用 init,因为里面需要用到master的值
        player.init();

        player.setCreateTime(now);
        player.setLastLoginTime(now);

        PlayerModel playerModel = player.save();
        writePlayerMapper.insert(playerModel);
        //插入后才有id
        player.setId(playerModel.getId());

        //写入登录日志
        LoginLogModel loginLogModel = new LoginLogModel();
        loginLogModel.setChannel(channel.getNumber());
        loginLogModel.setPlayerIndex(playerModel.getObjectIndex());
        loginLogModel.setIp(ip);
        loginLogModel.setLoginType("LOGIN_TYPE_REGIST");
        loginLogModel.setCreateTime(now);
        writeLoginLogMapper.insert(loginLogModel);

        return  player;
    }


    @Override
    public void enterGame(PlayerController playerController, Player player, SGCommonProto.E_CHANNEL_TYPE channel,
                          SGCommonProto.E_LOGIN_TYPE loginType,int serverRuleId ,
                          String clientVersion ,NettyConnection connection) {
        player.createKey();

        if (playerController == null){
            playerController = new PlayerController(player, connection);
            playerController.setClientVersion(clientVersion);
            playerController.setServerRuleId(serverRuleId);
        }
        else
        {
            playerController.setTcpConnection(connection);
            connection.setObject(playerController);
            playerController.setServerRuleId(serverRuleId);
            playerController.setClientVersion(clientVersion);
        }

        playerController.setStatus(E_PlayerStatus.FREE);

        GameServer.getInstance().getWorldManager().playerEnterGame(playerController);

        MsgUtils.sendLogin(channel, loginType, playerController);

        if(loginType == SGCommonProto.E_LOGIN_TYPE.LOGIN_TYPE_DEFAULT)
        {
            TwoTuple<Long, Long> inDayTime = CoreUtils.getTimeActivity();
            queryTotalRechargeCount(playerController.getPlayer(), inDayTime.getFirst(), inDayTime.getSecond());
        }

        if(loginType != SGCommonProto.E_LOGIN_TYPE.LOGIN_TYPE_BATTLE_BACK)
        {
            //检测是否能进大地图
            WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(playerController);
            if(worldMapData != null)
            {
                if(worldMapData.isSingle())
                {
                    worldMapData.checkInitGarrison();
                }

                worldMapData.playerOnline(playerController);

            }
            //进入游戏更新在线时间
            OnlineRewardData onlineRewardData = playerController.getPlayer().getOnlineData();
            onlineRewardData.setBeginTime();
        }

//        LogUtils.debug("----进入游戏成功---------------------");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveOnlinePlayer(boolean logout)
    {
        List<PlayerController> playerList = GameServer.getInstance().getWorldManager().getPlayerList();

        String sql = "update player set name=?,avatar=?,camp=?,level=?,exp=?,vipLevel=?,vipExp=?,fc=?,money=?,bagInfo=?,challengeInfo=?,taskInfo=?,boonInfo=?,settingInfo=?,mailInfo=?,majorInfo=?,isDel=?" + (logout?",lastLogoutTime=NOW()":"")+ " where objectIndex=?";
        int count = playerList.size();
        if(count > 0)
            //批量更新玩家数据
            jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
                @Override
                public void setValues(PreparedStatement ps, int i) throws SQLException
                {
                    Player player = playerList.get(i).getPlayer();
                    ps.setString(1, player.name);
                    ps.setString(2, player.avatar);
                    ps.setInt(3, player.camp);
                    ps.setInt(4, player.getLv());
                    ps.setInt(5, player.getExp());
                    ps.setInt(6, player.getVipLevel());
                    ps.setInt(7, player.getVipExp());
                    ps.setInt(8, player.fc);
                    ps.setInt(9, player.money);
                    ps.setBytes(10, player.getExtInfo(BagInfo.class).getData());
                    ps.setBytes(11, player.getExtInfo(ChallengeInfo.class).getData());
                    ps.setBytes(12, player.getExtInfo(TaskInfo.class).getData());
                    ps.setBytes(13, player.getExtInfo(BoonInfo.class).getData());
                    ps.setBytes(14, player.getExtInfo(SettingInfo.class).getData());
                    ps.setBytes(15, player.getExtInfo(MailInfo.class).getData());
                    ps.setBytes(16, player.getExtInfo(MajorInfo.class).getData());
                    ps.setBoolean(17, player.isDel);
                    ps.setString(18, player.getObjectIndex());
                    if(i%100 == 0 && i > 0)
                        LogUtils.info("Update Save Player:" + player);
                }

                @Override
                public int getBatchSize() {
                    return count;
                }
            });
    }

    /**
     * 查询总的充值金额
     * @param player
     */

    @Override
    public void queryTotalRechargeCount(Player player, long activityStartTime, long activityEndTime) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("objectIndex", player.getObjectIndex());
        jsonObject.put("startTime", activityStartTime);
        jsonObject.put("endTime", activityEndTime);
        JSONObject result = HttpJsonUtils.httpPost(GameServer.getInstance().getAuthServerHost() + HttpFactory.SERVER_GET_TOTAL_RECHARGE_COUNT, jsonObject);
        if (result != null) {
            String resultCode = result.getString("code");
            if (Integer.parseInt(resultCode) == 0) {//成功
                RechargeRecordData recordData = player.getRechargeRecordData();
                recordData.clearRechargeCount();
                String json = result.getJSONObject("data").getString("list");
                List<QueryRechargeCount> list = JSONObject.parseArray(json, QueryRechargeCount.class);
                LogUtils.debug("总充值金额：" + list);
//                for (QueryRechargeCount count : list) {
////                    recordData.addRechargeCount(count.getType(), count.getCount() / 100);
////                }
                list.forEach((count)->recordData.addRechargeCount(count.getType(),count.getCount()/100));
            } else {
                LogUtils.error("查询充值总充值金额错误 resultCode = " + resultCode);
                return;
            }
        } else {
            LogUtils.error("查询充值总充值金额错误 result == null");
        }
    }

    @Override
    public void updatePlayer(Player player, boolean updateBase, Class... clsAry)
    {
        List<Player> players = new ArrayList<>();
        players.add(player);

        updatePlayers(players, updateBase, clsAry);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updatePlayers(List<Player> playerList, boolean updateBase, Class... clsAry)
    {
        if(playerList.size() == 0)
            return;

        if(!updateBase && clsAry.length == 0)
            return;

        StringBuilder sql = new StringBuilder();
        sql.append("UPDATE player SET ");

        if(updateBase)
            sql.append("name=?,avatar=?,camp=?,level=?,exp=?,vipLevel=?,vipExp=?,fc=?,money=?,isDel=?");

        StringBuilder temp = new StringBuilder();
        for(Class cls : clsAry)
        {
            if(cls.equals(BagInfo.class))
                temp.append(",bagInfo=?");

            if(cls.equals(ChallengeInfo.class))
                temp.append(",challengeInfo=?");

            if(cls.equals(TaskInfo.class))
                temp.append(",taskInfo=?");

            if(cls.equals(BoonInfo.class))
                temp.append(",boonInfo=?");

            if(cls.equals(SettingInfo.class))
                temp.append(",settingInfo=?");

            if(cls.equals(MailInfo.class))
                temp.append(",mailInfo=?");
        }

        if(temp.length() > 0)
        {
            if(updateBase)
                sql.append(temp.toString());
            else
                sql.append(temp.substring(1));
        }

        sql.append(" WHERE objectIndex=?");

        int count = playerList.size();
        //批量更新玩家数据

        jdbcTemplate.batchUpdate(sql.toString(), new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                Player player = playerList.get(i);
                int start = 0;
                if (updateBase) {
                    ps.setString(1, player.name);
                    ps.setString(2, player.avatar);
                    ps.setInt(3, player.camp);
                    ps.setInt(4, player.getLv());
                    ps.setInt(5, player.getExp());
                    ps.setInt(6, player.getVipLevel());
                    ps.setInt(7, player.getVipExp());
                    ps.setInt(8, player.fc);
                    ps.setInt(9, player.money);
                    ps.setBoolean(10, player.isDel);
                    start = 11;
                } else {
                    start = 1;
                }
                for (Class cls : clsAry) {
                    ps.setBytes(start++, player.getExtInfo(cls).getData());
                }
                ps.setString(start, player.getObjectIndex());
            }

            @Override
            public int getBatchSize() {
                return count;
            }
        });
    }


    @Override
    public void updatePlayers(boolean updateBase, Class[] clsAry, Player... players)
    {
        if(players.length == 0)
            return;

        if(!updateBase && clsAry.length == 0)
            return;

        List<Player> playerList = new ArrayList<>();
        for(Player player : players)
            playerList.add(player);

        updatePlayers(playerList, updateBase, clsAry);
    }





    @Override
    public int getAllPlayerCount(String keyword)
    {
        return readPlayerMapper.findAllCount(keyword);
    }


    @Override
    public List<PlayerModel> getPlayerList(Integer page, Integer count, String keyword)
    {
        if(page <= 0 || count <= 0)
            return null;

        return readPlayerMapper.findList((page - 1) * count, count, keyword);
    }

    @Override
    public List<PlayerModel> findListByGroupMail(int camp, int minLevel, int maxLevel, int lastLoginDays) {
        return readPlayerMapper.findListByGroupMail(camp, minLevel, maxLevel,lastLoginDays);
    }


    /**
     * 充值
     * @param playerController
     */
    @Override
    public boolean recharge( PlayerController playerController, Player player, RechargeParam rechargeParam, int realRmb, String orderNo, String payType, boolean isTest) {

        LogUtils.debug("充值参数：" + rechargeParam);
        int rechargeId = rechargeParam.getRechargeId();
        /**
         * 获取配置
         */
        RechargeConfig rechargeConfig = DataFactory.getInstance().getGameObject(DataFactory.RECHARGE_KEY, rechargeId);
        if(rechargeConfig == null){
            LogUtils.error("充值id找不到...");
            if(playerController != null){
                playerController.sendWarn(WordFactory.PARAM_ERROR);
            }
            return false;
        }

        LogUtils.info("isTest -> " + isTest);
        /**
         * 测试账户验证
         */
        if(!isTest && !CoreUtils.isRechargeTestAccount(player.getAccount()) && !SpringContext.isDev() && !GameServer.getInstance().getWorldManager().isWhite(player.getAccount()))
        {
            //苹果支付的金额单位是元,其它的暂时是分
            String appstore = PayUtils.getEnumType(SGCommonProto.E_RECHARGE_TYPE.RECHARGE_TYPE_APPSTORE.name());
            int checkRmb = appstore.equals(payType) ? rechargeConfig.rmb : rechargeConfig.rmb * 100;
            if(realRmb < checkRmb){
                LogUtils.error("充值金额错误,真实：" + realRmb + ", 配置:" + checkRmb + ", payType:" + payType);
                if(playerController != null){
                    playerController.sendWarn(WordFactory.PARAM_ERROR);
                }
                return false;
            }
        }

        /**
         * 增加用户总充值金额
         */
        player.getRechargeData().addRechargeCount(rechargeConfig.rmb);
        //检测开服活动是否完成
        player.getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_5,rechargeConfig.rmb);
        RechargeRecordData recordData = player.getRechargeRecordData();
        BagInfo bagInfo = player.getExtInfo(BagInfo.class);
        boolean sendMail = false;
        boolean hasRechargeThis = recordData.getRechargeRecordMap().get(rechargeId) != null;
        //如果是月卡或者周卡
        if(rechargeConfig.type == E_RechargeGoodsType.MOUTH_CARD.getCode() ||
                rechargeConfig.type == E_RechargeGoodsType.WEEK_CARD.getCode()){
            if(recordData.hasRechargeRecord(rechargeId)) {//曾经购买过
                //原来是按毫秒算的 现在直接按照天算
                long endTime = recordData.getRechargeRecordMap().get(rechargeId).getEndTime();
                long max = Math.max(DataFactory.currentTime, endTime);
                //这里的月卡 或者 周卡 都是根据配置的天数算的 跟本月实际有多少天没有关系
                recordData.addRecord(rechargeId, max + ConstantFactory.DAY_TIME * rechargeConfig.days);
            }else {
                recordData.addRecord(rechargeId, DataFactory.currentTime + ConstantFactory.DAY_TIME * rechargeConfig.days);
            }
            bagInfo.addGoods(rechargeConfig.goods, null);
            sendMail = true;
        }else if(rechargeConfig.type == E_RechargeGoodsType.DIAMOND.getCode()){
            bagInfo.addGoods(rechargeConfig.goods, null);
            if(recordData.getRechargeRecordMap().get(rechargeId) == null){
                bagInfo.addGoods(rechargeConfig.extra, null);
            }
            recordData.addRecord(rechargeId, 0);
            TimePropDB timeProp = null;
            if(!Utils.isNullOrEmpty(rechargeParam.getUniqueId())){
                timeProp = player.getBagInfo().getTimePropData().getTimeProp(rechargeParam.getUniqueId());
                if(timeProp == null){
                    LogUtils.error("优惠卷不存在:" + rechargeParam);
                }else {
                    if(!timeProp.isTimeIn()){
                        LogUtils.error("优惠卷已过期" + rechargeParam);
                    }else if(timeProp.isUse){
                        LogUtils.error("优惠卷已被使用" + rechargeParam);
                        timeProp = null;
                    }else if(rechargeConfig.rmb * 10 < timeProp.getConfig().timePropData.type){
                        LogUtils.error("充值钻石不够，不能使用优惠券");
                        timeProp = null;
                    }
                }

                if(timeProp != null){
                    bagInfo.addAsset(ConfigFactory.ASSET_MONEY_KEY, timeProp.getConfig().timePropData.id);
                    timeProp.useTimeProp(player);
                }
            }
            sendMail = true;
        }else if(rechargeConfig.type == E_RechargeGoodsType.OPEN_FUND.getCode()){
            BonusData bonusData = player.getBonusData();
            bonusData.buyFund(SGCommonProto.E_FUND_TYPE.FUND_TYPE_OPEN);
            recordData.addRecord(rechargeId, 0);
            sendMail = true;
        }else if(rechargeConfig.type == E_RechargeGoodsType.NEW_SERVER_FUND.getCode()){
            BonusData bonusData = player.getBonusData();
            bonusData.buyFund(SGCommonProto.E_FUND_TYPE.FUND_TYPE_NEW_SERVER);
            recordData.addRecord(rechargeId, 0);
            sendMail = true;
        }else if(rechargeConfig.type == E_RechargeGoodsType.DAILY_GIFT.getCode()){
            recordData.addDailyGiftRecord(rechargeId);
            bagInfo.addGoods(rechargeConfig.goods, null);
            sendMail = true;
        }else if(rechargeConfig.type == E_RechargeGoodsType.FLASH_SALE.getCode()){
            if(rechargeConfig.linkId > 0){
                player.getBonusData().buyFlashSale(rechargeConfig.linkId);
                bagInfo.addGoods(rechargeConfig.goods, null);
                recordData.addRecord(rechargeId, 0);
                sendMail = false;
            }
        }else if(rechargeConfig.type == E_RechargeGoodsType.OPEN_SERVER_BOON.getCode()){
           //TODO 开服红利暂时不加这个功能  设置为已购买
            player.getSevenDayData().setBuyWelfareGift(true);
//            WorldInfoFactory worldInfoFactory= WorldInfoFactory.getInstance();
//            //总购买数量加1
//            WorldInfoFactory.getInstance().setBonusCount(worldInfoFactory.getBonusCount()+1);
//            bagInfo.addGoods(rechargeConfig.goods, null);
//            sendMail = true;
        }

        int receiveExp = rechargeConfig.rmb * 10;
        player.addVipExp(receiveExp);

        if(sendMail){
            MailDB mailDB = getRechargeMailContent(rechargeId, hasRechargeThis);
            if(mailDB != null){
                player.getExtInfo(MailInfo.class).addMail(SGCommonProto.E_MAIL_TYPE.MAIL_TYPE_RECHARGE_VALUE, mailDB);
            }else {
                LogUtils.debug("充值邮件为空，请检查");
            }
        }
        GameServer.getInstance().getWorldManager().updateRankInfo(SGCommonProto.E_RANK_TYPE.RANK_TYPE_MONEY, player, player.getVipExp());
        if(payType != null && payType.startsWith("GM"))
        {
            String[] strs = payType.split(ConstantFactory.UNDERLINE);
            GMLogModel model = new GMLogModel();
            model.setPlayerIndex(player.getObjectIndex());
            model.setType(CodeFactory.GM_PLAYER_RECHARGE);
            model.setValue(realRmb+"");
            model.setOptionPerson(strs.length>1?strs[1]:"null");
            String temp = "";
            if(player != null)
                temp = "目标玩家->" + player.getName() + ",";
            temp += "操作内容->";
            model.setContent(temp + "充值:RMB=" + realRmb + "分,钻石=" + (rechargeConfig.goods[0].value + rechargeConfig.extra[0].value));
            writeGMLogMapper.insert(model);
        }

        if(playerController != null){
            GameServer.getInstance().startThread(()->{
                SGPlayerProto.S2C_RechargeResult.Builder response = SGPlayerProto.S2C_RechargeResult.newBuilder();
                response.setVipExp(playerController.getPlayer().getVipExp());
                response.setVipLv(playerController.getPlayer().getVipLevel());
                RechargeConfig config;
                for(Map.Entry<Integer, RechargeRecordData.MouthCardRecord> entry : recordData.getRechargeRecordMap().entrySet())
                {
                    config = DataFactory.getInstance().getGameObject(DataFactory.RECHARGE_KEY, entry.getKey());
                    if (config == null)
                        continue;
                    if(config.type == E_RechargeGoodsType.MOUTH_CARD.getCode() || config.type == E_RechargeGoodsType.WEEK_CARD.getCode()){
                        //获取月卡剩余天数
                        long endTime = entry.getValue().getEndTime();
                        if(DataFactory.currentTime <= endTime){
                            //获取剩余天数
                            int day = CoreUtils.getBetweenDay24(DataFactory.currentTime, endTime);
                            if(day != 0){
                                response.addMouthCards(SGCommonProto.MouthCard.newBuilder().setId(entry.getKey()).setEndDays(day).build());
                            }
                        }
                    }else if(config.type == E_RechargeGoodsType.DIAMOND.getCode() || config.type == E_RechargeGoodsType.OPEN_FUND.getCode()){
                        response.addHasBuyRechargeId(entry.getKey());
                    }
                }

                response.setAddVipExp(receiveExp);
                response.setRecharId(rechargeId);
                response.setCurrentServerTime(DataFactory.currentTime);
                response.setOrderNo(orderNo == null ? "" : orderNo);
                response.setClientParam(rechargeParam.getClientParam());
                LogUtils.debug("返回给客户端充值结果信息" + response);
                playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Bonus_RechargeResult_VALUE, response.build().toByteArray());
                MsgUtils.addPlayerGoodsChange(SGMainProto.E_MSG_ID.MsgID_Bonus_RechargeResult_VALUE, playerController);
                SendUtils.sendChangeData(0, playerController);
                SendUtils.mailPush(SGCommonProto.E_MAIL_TYPE.MAIL_TYPE_RECHARGE, playerController);
            });
        }else {
            update(player);
        }

        return true;

    }




    public MailDB getRechargeMailContent(int rechargeId, boolean isFirstRechargeComplete){
        RechargeConfig rechargeConfig = DataFactory.getInstance().getGameObject(DataFactory.RECHARGE_KEY, rechargeId);
        String suffix = "";
        if (rechargeConfig.rmb > 6){
            MailConfig suffixConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.MAIL_RECHARGE_SUFFIX.getCode());
            if (suffixConfig != null){
                suffix = suffixConfig.content;
            }
        }
        if(rechargeConfig != null){
            if(rechargeConfig.type == E_RechargeGoodsType.DIAMOND.getCode()){
                if(!isFirstRechargeComplete){
                    MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.RECHARGE_WITH_EXTRA.getCode());
                    return new MailDB(mailConfig.title + suffix, MessageFormat.format(mailConfig.content, rechargeConfig.rmb,
                            rechargeConfig.goods[0].value,rechargeConfig.extra[0].value), null);

                }else {
                    MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.RECHARGE.getCode());
                    return new MailDB(mailConfig.title, MessageFormat.format(mailConfig.content + suffix, rechargeConfig.rmb, rechargeConfig.goods[0].value), null);
                }

            }

            if(rechargeConfig.type == E_RechargeGoodsType.OPEN_FUND.getCode()){
                MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.OPEN_FUND_RECHARGE.getCode());
                return new MailDB(mailConfig.title, mailConfig.content + suffix, null);
            }

            if(rechargeConfig.type == E_RechargeGoodsType.NEW_SERVER_FUND.getCode()){
                MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.NEW_SERVER_FUND_RECHARGE.getCode());
                return new MailDB(mailConfig.title, mailConfig.content + suffix, null);
            }

            if(rechargeConfig.type == E_RechargeGoodsType.WEEK_CARD.getCode()){
                String name = CoreUtils.getGoodsName(rechargeConfig.goods[0]);
                MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.WEEK_CARD.getCode());
                return new MailDB(MessageFormat.format(mailConfig.title, name), MessageFormat.format(mailConfig.content + suffix, name,
                        rechargeConfig.goods[0].value, rechargeConfig.days, rechargeConfig.extra[0].value), null);
            }

            if(rechargeConfig.type == E_RechargeGoodsType.DAILY_GIFT.getCode()){
                MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.DAILY_GIFT.getCode());
                return new MailDB(MessageFormat.format(mailConfig.title, rechargeConfig.rmb),
                        MessageFormat.format(mailConfig.content + suffix, rechargeConfig.rmb), null);
            }

            if(rechargeConfig.type == E_RechargeGoodsType.MOUTH_CARD.getCode()){
                MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.MOUTH_CARD.getCode());
                return new MailDB(MessageFormat.format(mailConfig.title, rechargeConfig.rmb), MessageFormat.format(mailConfig.content + suffix, rechargeConfig.rmb,
                        rechargeConfig.goods[0].value, rechargeConfig.days, rechargeConfig.extra[0].value), null);
            }


//            if(rechargeConfig.type == E_RechargeType.DIAMOND.getCode()){
//                if(!isFirstRechargeComplete){
//                    MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.RECHARGE_WITH_EXTRA.getCode());
//                    return new MailDB(mailConfig.title, MessageFormat.format(mailConfig.content, rechargeConfig.rmb,
//                            rechargeConfig.goods[0].value,rechargeConfig.extra[0].value), null);
//                }else {
//                    MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.RECHARGE.getCode());
//                    return new MailDB(mailConfig.title, MessageFormat.format(mailConfig.content, rechargeConfig.rmb, rechargeConfig.goods[0].value), null);
//                }
//
//            }else if(rechargeConfig.type == E_RechargeType.WEEK_CARD.getCode()){
//                MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.RECHARGE.getCode());
//                return new MailDB(mailConfig.title, MessageFormat.format(mailConfig.content, rechargeConfig.rmb, rechargeConfig.goods[0].value), null);
//            }
        }
        return null;
    }

    @Override
    public void updateMobile(String mobile, long uid) {
        writeUserMapper.updateMobile(mobile, uid);
    }

    @Override
    public void updateAccount(String account, long uid) {
        writeUserMapper.updateAccount(account, uid);
    }

    @Override
    public SGCommonProto.E_CAMP_TYPE getMinPlayerCountCampType() {
        Integer BRIGHTCount = readPlayerMapper.getMinPlayerCountCamp(SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_BRIGHT_VALUE);
        BRIGHTCount = BRIGHTCount == null ? 0 : BRIGHTCount;
        Integer BLOODYCount = readPlayerMapper.getMinPlayerCountCamp(SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_BLOODY_VALUE);
        BLOODYCount = BLOODYCount == null ? 0 : BLOODYCount;
        Integer DARKCount = readPlayerMapper.getMinPlayerCountCamp(SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_DARK_VALUE);
        DARKCount = DARKCount == null ? 0 : DARKCount;
        int min = Math.min(Math.min(BRIGHTCount, BLOODYCount), DARKCount);
        if(min == BRIGHTCount){
            return SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_BRIGHT;
        }else if(min == BLOODYCount){
            return SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_BLOODY;
        }else {
            return SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_DARK;
        }

    }

    @Override
    public void feedBack(String playerIndex, String content) {
        writeFeedbackMapper.insert(new FeedbackModel(playerIndex, content));
    }

    @Override
    public int getMyFCRank(int myFC) {
        return readPlayerMapper.getMyFCRank(myFC);
    }


    @Override
    public List<String> getRobotPlayerByMaxCount(int count) {
        return readPlayerMapper.getRobotPlayerByMaxCount(count);
    }


    @Override
    public void deletePlayer(List<PlayerModel> playerList) {
        writePlayerMapper.delete(playerList);
    }

    @Override
    public Map<String, Object> getNameAvatarInfo(String playerIndex) {
        return readPlayerMapper.getPlayerNameAvatar(playerIndex);
    }

    @Override
    public int getWorldPlayerAverageLevel(int count, int functionId) {
        List<PlayerModel> playerListByIndex = readPlayerMapper.getTopPlayer(count);
        int size = playerListByIndex.size();
        int sum = 0;
        for(PlayerModel model : playerListByIndex){
            sum += model.getLevel();
        }
        sum = sum == 0 ? 1 : (sum / size);
        FunctionConfig config = DataFactory.getInstance().getGameObject(DataFactory.FUNCTION_KEY, functionId);
        if(config != null){
            sum = sum < config.lv ? config.lv  + 1 : sum;
        }
        return sum;
    }



}
